home *** CD-ROM | disk | FTP | other *** search
/ Reverse Code Engineering RCE CD +sandman 2000 / ReverseCodeEngineeringRceCdsandman2000.iso / RCE / Library / Manuels & Misc / Assembly / AOA.ZIP / CH09 / EX9_4.ASM < prev    next >
Encoding:
Assembly Source File  |  1996-02-08  |  4.0 KB  |  199 lines

  1. ; EX9_4.asm
  2. ;
  3. ; Hardware-based software timing loop example.
  4.  
  5.         .xlist
  6.         include     stdlib.a
  7.         includelib    stdlib.lib
  8.         .list
  9.  
  10. ; Location of BIOS variables:
  11.  
  12. RTC        textequ    <es:[6ch]>        ;Real Time Clock variable.
  13.  
  14.  
  15. dseg        segment    para public 'data'
  16.  
  17.  
  18. ; Dummy is a variable the timing loop compares against itself to match
  19. ; the timing in the InitDelay routine.
  20.  
  21. Dummy        word    0
  22.  
  23.  
  24. ; Timed value is an empirically determined constant which provides a
  25. ; suitable delay on whatever machine we are running on.  The program
  26. ; computes a reasonable value for this variable.
  27.  
  28. TimerValue    dword    0
  29.  
  30.  
  31. dseg        ends
  32.  
  33.  
  34. cseg        segment    para public 'code'
  35.         assume    cs:cseg, ds:dseg
  36.  
  37.  
  38. wp        textequ    <word ptr>
  39.  
  40.  
  41. ; Initialize the TimerValue variable that contains the number of loop
  42. ; interations for a 1/18th second delay.
  43.  
  44. InitDelay    proc
  45.         push    es
  46.         push    ax
  47.  
  48. ; Okay, let's see how long it takes to count down 1/18th of a second.
  49. ; RTC is a magic location in the BIOS variables (segment 40h) which
  50. ; the Real Time Clock code increments every 55 ms (about 1/18.2 secs).
  51. ; This code waits for this location to change, then it counts off how
  52. ; long it takes to change again.  By executing that same loop again
  53. ; we can get (roughly) equivalent time delays on two separate machines.
  54.  
  55.  
  56.         mov    ax, 40h            ;Segment address of BIOS vars.
  57.         mov    es, ax
  58.         mov    ax, RTC            ;Wait for timer to change.
  59. RTCMustChange:    cmp    ax, RTC
  60.         je    RTCMustChange
  61.  
  62. ; Okay, begin timing the number of iterations it takes for an 18th of a
  63. ; second to pass.  The align directive ensures that this loop and Delay's
  64. ; corresponding loop both fall on the same cache line boundary.
  65.  
  66.         mov    wp TimerValue, 0
  67.         mov    wp TimerValue+2, 0
  68.         mov    ax, RTC
  69.  
  70.         align    16
  71.  
  72. TimeRTC:    cmp    ax, RTC
  73.         jne    TimerDone
  74.  
  75.         sub    wp TimerValue, 1
  76.         sbb    wp TimerValue+2, 0
  77.         jne    TimeRTC
  78.         cmp    wp TimerValue, 0
  79.         jne    TimeRTC
  80.  
  81. ; Negate the count down value and decrement it to compute the number
  82. ; of times the delay loop must repeat the loop above.
  83.  
  84. TimerDone:    neg    wp TimerValue+2        ;32-bit negate of
  85.         neg    wp TimerValue        ; TimerValue.
  86.         sbb    wp TimerValue+2, 0
  87.  
  88.         pop    ax
  89.         pop    es
  90.         ret
  91. InitDelay    endp
  92.  
  93.  
  94.  
  95.  
  96.  
  97.  
  98. ; Delay-    This routine delays for roughly a fixed time period on
  99. ;        any machine, regardless of CPU or clock rate (May vary by
  100. ;        a factor of two or so, but it not as sensitive to CPU
  101. ;        speed as a simple LOOP instr).
  102.  
  103. Delay        proc
  104.         push    es
  105.         push    ax
  106.  
  107.         mov    ax, dseg
  108.         mov    es, ax
  109.  
  110.         push    wp TimerValue+2        ;Save these values
  111.         push    wp TimerValue        ; so we can modify them
  112.         mov    ax, Dummy        ;Compare this with itself.
  113.  
  114.         align    16
  115.  
  116. TimeRTC:    cmp    ax, es:Dummy
  117.         jne    DelayDone        ;Never taken.
  118.  
  119.         sub    wp TimerValue, 1
  120.         sbb    wp TimerValue+2, 0
  121.         jne    TimeRTC
  122.         cmp    wp TimerValue, 0
  123.         jne    TimeRTC
  124.  
  125.  
  126. DelayDone:
  127.         pop    wp TimerValue
  128.         pop    wp TimerValue+2
  129.         pop    ax
  130.         pop    es
  131.         ret
  132. Delay        endp
  133.  
  134.  
  135.  
  136.  
  137. Main        proc
  138.         mov    ax, dseg
  139.         mov    ds, ax
  140.         mov    es, ax
  141.  
  142.  
  143.         call    InitDelay
  144.  
  145.         printf
  146.         byte    cr,lf
  147.         byte    "Hardware Based Software delay loop test",cr,lf
  148.         byte    "---------------------------------------",cr,lf,lf
  149.         byte    "Delay factor: %ld",cr,lf
  150.         byte    cr,lf
  151.         byte    "Press any key to begin an 11 second delay "
  152.         byte    "(approx).",0
  153.         dword    TimerValue
  154.  
  155.         getc
  156.         putcr
  157.         mov    cx, 200        ;55 msec * 200 = 11 sec.
  158. Delay18:    call    Delay
  159.         loop    Delay18
  160.  
  161.         print
  162.         byte    cr,lf
  163.         byte    "Delay complete.",cr,lf
  164.         byte    cr,lf
  165.         byte    "If you have a turbo button on your PC, press it "
  166.         byte    "now to see the effect",cr,lf
  167.         byte    "of clock speed on a software delay loop.",cr,lf
  168.         byte    "Press any key to start timing delay.",0
  169.  
  170.         getc
  171.         putcr
  172.         mov    cx, 200        ;55 msec * 200 = 11 sec.
  173. Delay18a:    call    Delay
  174.         loop    Delay18a
  175.  
  176.         print
  177.         byte    cr,lf
  178.         byte    "Delay Complete",cr,lf,0
  179.  
  180.  
  181.  
  182.  
  183. Quit:        ExitPgm            ;DOS macro to quit program.
  184. Main        endp
  185.  
  186. cseg            ends
  187.  
  188.  
  189.  
  190. sseg        segment    para stack 'stack'
  191. stk        db    1024 dup ("stack   ")
  192. sseg        ends
  193.  
  194.  
  195. zzzzzzseg    segment    para public 'zzzzzz'
  196. LastBytes    db    16 dup (?)
  197. zzzzzzseg    ends
  198.         end    Main
  199.